#pragma once
#include "requestor.hpp"
/*
    RpcCaller模块:向上层用户提供调用接口;底层调用了 客户端管理请求模块(requestor)的send
*/
namespace tmh_rpc
{
    namespace client
    {
        // requestor中的处理是针对BaseMessage进行处理的
        // RpcCaller中针对结果的处理是针对RpcResponse里面的result进行处理的
        class RpcCaller
        {
        public:
            using ptr = std::shared_ptr<RpcCaller>;
            // 异步调用和回调的处理结果类型
            using JsonAsyncResponse = std::future<Json::Value>;
            using JsonResponseCallback = std::function<void(const Json::Value &)>;

            RpcCaller(const Requestor::ptr &requestor) : _requestor(requestor) {}

            // 同步调用
            bool call(const BaseConnection::ptr &conn, const string &method,
                      const Json::Value &params, Json::Value &result)
            {
                DLOG("开始同步Rpc调用...");

                // 1. 组织请求
                auto req_msg = MessageFactory::create<RpcRequest>();

                req_msg->setId(UUID::uuid());
                req_msg->setMType(MType::REQ_RPC);
                req_msg->setMethod(method);
                req_msg->setParameter(params);

                // 2. 发送请求
                BaseMessage::ptr rsp_msg;
                bool ret=false;
                //对转换类型进行判断
                auto req=std::dynamic_pointer_cast<BaseMessage>(req_msg);
                if(req==nullptr){
                    DLOG("类型转换失败...");
                }else{
                    DLOG("调用Requestor模块发送请求...");
                    ret = _requestor->send(conn, req, rsp_msg);
                }

                if (ret == false)
                {
                    ELOG("同步Rpc请求失败!");
                    return false;
                }

                DLOG("收到响应,进行解析,获取结果!");
                // 3. 等待响应:rsp_msg是输入输出型参数;
                auto rpc_rsp_msg = std::dynamic_pointer_cast<RpcResponse>(rsp_msg);
                if (!rpc_rsp_msg)
                {
                    ELOG("rpc响应向下类型转换失败!");
                    return false;
                }

                if (rpc_rsp_msg->rcode() != RCode::RCODE_OK)
                {
                    ELOG("rpc请求出错:%s", errReason(rpc_rsp_msg->rcode()).c_str());
                    return false;
                }
                result = rpc_rsp_msg->result();
                DLOG("结果设置完毕");
                return true;
            }

            // 异步调用
            bool call(const BaseConnection::ptr &conn, const string &method,
                      const Json::Value &params, JsonAsyncResponse &result)
            {
                // 1. 组织请求
                auto req_msg = MessageFactory::create<RpcRequest>();
                req_msg->setId(UUID::uuid());
                req_msg->setMType(MType::REQ_RPC);
                req_msg->setMethod(method);
                req_msg->setParameter(params);

                // 2. 向服务器发送异步调用请求,设置回调函数,回调函数中会传入一个promise对象,在回调函数中去对promise设置数据
                auto json_promise = std::make_shared<std::promise<Json::Value>>();
                // std::promise<Json::Value> json_promise;
                result = json_promise->get_future();
                Requestor::RequestCallback cb = std::bind(&RpcCaller::Callback, this,
                                                          json_promise, std::placeholders::_1);
                bool ret = _requestor->send(conn, std::dynamic_pointer_cast<BaseMessage>(req_msg), cb);
                if (ret == false)
                {
                    ELOG("异步Rpc请求失败!");
                    return false;
                }
                // 3. 等待响应:用户在上层使用get获取响应结果
                return true;
            }

            // 回调处理
            bool call(const BaseConnection::ptr &conn, const string &method,
                      const Json::Value &params, const JsonResponseCallback &cb)
            {
                // 1. 组织请求
                auto req_msg = MessageFactory::create<RpcRequest>();
                req_msg->setId(UUID::uuid());
                req_msg->setMType(MType::REQ_RPC);
                req_msg->setMethod(method);
                req_msg->setParameter(params);

                // 2. 发送请求
                Requestor::RequestCallback req_cb = std::bind(&RpcCaller::Callback1, this,
                                                              cb, std::placeholders::_1);
                // 3. 等待响应
                bool ret = _requestor->send(conn, std::dynamic_pointer_cast<BaseMessage>(req_msg), req_cb);
                if (ret == false)
                {
                    ELOG("回调Rpc请求失败!");
                    return false;
                }
                // 3. 等待响应:用户在上层使用get获取响应结果
                return true;
            }

        private:
            // 用于回调处理的函数
            void Callback1(const JsonResponseCallback &cb, const BaseMessage::ptr &msg)
            {
                auto rpc_rsp_msg = std::dynamic_pointer_cast<RpcResponse>(msg);
                if (!rpc_rsp_msg)
                {
                    ELOG("rpc响应向下类型转换失败!");
                    return;
                }

                if (rpc_rsp_msg->rcode() != RCode::RCODE_OK)
                {
                    ELOG("rpc回调请求出错:%s", errReason(rpc_rsp_msg->rcode()).c_str());
                    return;
                }

                // 对结果进行回调处理
                cb(rpc_rsp_msg->result());
            }

            // 用于异步调用的回调函数
            void Callback(std::shared_ptr<std::promise<Json::Value>> result, const BaseMessage::ptr &msg)
            {
                auto rpc_rsp_msg = std::dynamic_pointer_cast<RpcResponse>(msg);
                if (!rpc_rsp_msg)
                {
                    ELOG("rpc响应向下类型转换失败!");
                    return;
                }

                if (rpc_rsp_msg->rcode() != RCode::RCODE_OK)
                {
                    ELOG("rpc异步请求出错:%s", errReason(rpc_rsp_msg->rcode()).c_str());
                    return;
                }
                result->set_value(rpc_rsp_msg->result());
            }

        private:
            // 通过Rpcrequestor模块进行发送
            Requestor::ptr _requestor;
        };
    }
}